package.cpath = "luaclib/?.so;3rd/lua-cjson/?.so;"
local skynet = require "skynet"
local socket = require "socket"
require "skynet.manager"	-- import skynet.register
require "config_redis"
local mysql = require "mysql"
local redis = require "redis"
local json   = require "cjson"


local HALL_KEY = {}  
HALL_KEY.hall_service = 'service'      --房间service_name
HALL_KEY.hall_room_service_name = 'room_service_name'      --房间service_name
HALL_KEY.service_list = 'new_service_list'      --房间service_name
HALL_KEY.cost_card_0 = 'cost_card_0'      --房间service_name
HALL_KEY.cost_card_1 = 'cost_card_1'      --房间service_name
HALL_KEY.cost_card_2 = 'cost_card_2'      --房间service_name

local mysql_db
local function start_mysql(args)
	local function on_connect(db)
		db:query("set charset ".. args.charset);
	end	
	mysql_db=mysql.connect{
		host	= args.host,
		port	= args.port,
		database= args.database,
		user	= args.user,
		password= args.password,
		max_packet_size = 1024 * 1024,
		on_connect = on_connect,
	}
end

local redis_db 
local function start_redis(args)
	redis_db = redis.connect(args)
end

CMD = {}

function CMD.get_config_gold_buy_type()
	return gold_buy_type 
end

function CMD.get_config_gold_buy_type_first()
	return gold_buy_type_first 
end

function CMD.gold_buy_type_first_ac()
	return gold_buy_type_first_ac 
end

function CMD.gold_buy_type_ac()
	return gold_buy_type_ac 
end


function CMD.get_config_cost_gold_conf(typ) 
	if cost_gold_conf[typ] ~= nil then  
		return cost_gold_conf[typ] 
	else
		typ = typ .. '8'
		if cost_gold_conf[typ] ~= nil then 
			return cost_gold_conf[typ]
		end
	end
	return 2
end
---------------------------------begin mysql function---------------------------------
 

function CMD.mysql_get_one(sql) 
    local ok = false 
    sql = sql .. ' limit 0,1'
    local res = mysql_db:query(sql) 
    if #res == 0 then
        return ok
    end
    ok = true 
    return res[1]
end

function CMD.mysql_get_all(sql) 
    local ok = false 
    local res = mysql_db:query(sql) 
    if #res == 0 then
        return ok
    end  
    return res
end

function CMD.mysql_insert(sql) 
    local res = mysql_db:query(sql) 
    local ok = false
    if res and res.errno then
        return ok
    end
    ok = res.insert_id
    return ok 
end

function CMD.mysql_update(sql) 
    mysql_db:query(sql) 
end


function CMD.mysql_del(sql) 
    mysql_db:query(sql) 
end


---------------------------------begin redis function---------------------------------

function CMD.redis_get(key)   
    return redis_db:get( key ) 
end


--del  key 
function CMD.redis_del(key) 
    return redis_db:del( key )  
end

--hget  key 
function CMD.redis_hgetall(key) 
    local data = redis_db:hgetall( key )  
    local rs = {}
    if data ~= nil then  
        for k,v in pairs(data) do
            if k % 2 == 1 then
                rs[v] = data[k+1]
            end 
        end
    end
    return rs
end
 

--del  key 
function CMD.redis_hdel(key,feid) 
    return redis_db:hdel( key,feid )  
end

--lpush  在名称为key的list头添加一个值为value的 元素 
function CMD.redis_lpush(key,value) 
    return redis_db:lpush( key,value )  
end

--返回名称为key的list的长度
function CMD.redis_llen(key ) 
    return redis_db:lpush( key  )  
end

--返回名称为key的list中start至end之间的元素（下标从0开始
function CMD.redis_lrange(key, start, endnum ) 
    return redis_db:lrange( key, start, endnum  )  
end

--返回名称为key的list中start至end之间的元素（下标从0开始
function CMD.redis_ltrim(key, start, endnum ) 
    return redis_db:ltrim( key, start, endnum  )  
end

--根据参数 count 的值，移除列表中与参数 value 相等的元素。
function CMD.redis_lrem(key, count , value ) 
    return redis_db:lrem( key, count , value  )  
end
 
---------------------------------begin rooms function---------------------------------
local rooms = {}

function CMD.redis_addroom(appstore)
	while true
	do
		math.randomseed( getmicrosecond() )
		local room_id = 100000
		if appstore == 1 then 
			room_id = math.random(100000,110000)
		else
			room_id = math.random(110000,999999)
		end 
		if rooms[room_id] == nil then  
			return room_id
		end
	end
end

function CMD.hall_name_hset(room_id,hall_name)
	rooms[room_id] = hall_name
end

function CMD.hall_name_hget(room_id)
	if rooms[room_id] then 
		return rooms[room_id]
	end
	return 'MAJAING_HALL'
end 

function CMD.clean_room_redis(id)
	local room_id = math.ceil(id)  
	rooms[room_id] = nil 
end
 

local function get_service_now()  
    -- local service_all = CMD.redis_hgetall('service')  
    -- local num = 9999999
    -- local service_name = nil
    -- for v,k in pairs(service_all) do
    --     v = tonumber(v)
    --     if v > 0 and num > v then
    --         num = v
    --         service_name = k
    --     end
    -- end 
    -- if service_name == nil then   --没有配置  默认第一个 
    --     service_name = config_service_name_now
    -- end
    return config_service_name_now
end

function CMD.get_service(id) 
  --   local room_id = math.ceil(id) 
  --   local service_name = redis_db:hget(HALL_KEY.hall_room_service_name,room_id) 
  --   if service_name == nil then 
		-- service_name =  get_service_now()  
		-- redis_db:hset(HALL_KEY.hall_room_service_name,room_id,service_name) --当前房间ID 
  --   end
    return config_service_name_now
end 

function CMD.get_version( )  
    return redis_db:get(  'version' ) 
end 

---------------------------------end rooms function---------------------------------

function CMD.apple_trans(uid, data) 
	local form = {transactions = data.transactions,uid = uid}
	local status, body = httpc.post(bint_invite_url, '/charge_iap.php', form, respheader);
	if status == 200 then 
		local rearr = json.decode(body)
		return { errno = rearr.errno, msg = rearr.msg, transactions = rearr.transactions }
	else
		return { errno = 1, msg = "支付失败"}
	end
end

-- 获取用户数据
function CMD.get_user(uid)
    local ok = false
    --local ret = mongo_db[db_name].testdb:findOne({uid = uid})
	local query_sql = string.format("select * from user where uid = %d",uid)
	local res = mysql_db:query(query_sql)
	
    if #res == 0 then
        return ok
    end
    ok = true
    return ok,res[1]
end

-- 保存数据要防止重入问题，待解决
function CMD.unset_user(uid,key,index)
    local ok = false
    local save = {}
    local newKey = key.."."..index      -- 使用内嵌访问的方式修改数组
    save[newKey] = 1
    --mongo_db[db_name].testdb:findAndModify({query = {uid = uid}, update = {["$unset"] = save}, upsert = true })
    ok = true
    return ok
end

function get_uid( )            
	math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) ) 
	local uid = math.random(100000,999999); 
	local query_sql = string.format("select * from user where uid = %d",uid)
	local res = mysql_db:query(query_sql)
	
    if #res == 0 then
        return uid
    else
    	return get_uid( )     
    end 
end

function CMD.insert_user(account,name,sex,head,ip,channel,password,expires_time)
	local uid = get_uid( )     
	local new_user_card = 10 
	local query_sql = string.format("insert into `user` values( %d,'%s','%s','%s', %d, %d, 50, unix_timestamp(),unix_timestamp(),'%s', 0,0,'%s','%s',%d, '0', '0', '0', '0', '0','2017-01-01 00:00:00.000000')",uid, account, password, name, sex, new_user_card, ip, channel,head,expires_time)
	local res = mysql_db:query(query_sql)
	local ok = false
    if res and res.errno then
        return ok
    end
    ok = uid
    CMD.card_log(uid, 1, new_user_card, new_user_card, 7)  
    return ok
end

function CMD.set_user(uid,key,index,save)
    local ok = false
    if index then
        local newKey = key.."."..index      -- 使用内嵌访问的方式修改数组
        save[newKey] = save[key][index]
        save[key] = nil
    end
	
	local sql = "update user set "
	local set 
	for k,v in pairs(save) do
		if set == nil then
			set = string.format("%s='%s'",k,v)
		else
			set = string.format("%s='%s',",k,v)..set
		end
	end
	sql = sql..set.." where uid = "..uid
	local ret = mysql_db:query(sql)	
	
	if ret then
		ok = true
	else
		ok = false	
	end
    return ok
end

-- 添加订单
function CMD.insert_order(data) 
	local ok = 0
	local query_sql = string.format("insert into `order` values(NULL,%d, '%s','%s',%d,'%s',%d,%d,'%s')", data.uid, data.plat,data.order_id,data.amount,data.product_id,data.create_time,data.status,data.ext_info);
	local res = mysql_db:query(query_sql)
	--local str = json.encode(res)
    if res and res.errno then
        return ok
    end
    ok = res.insert_id
    return ok
end

function CMD.save_logdata(room_id,cur_ju,content)
	local ok = 0
	local query_sql = string.format("insert into `logdata` values(NULL, '%d', '%d',unix_timestamp(), '%s')",room_id,cur_ju, json.encode(content));
	local res = mysql_db:query(query_sql) 
    if res and res.errno then
        return ok
    end
    ok = res.insert_id
    return ok
end


function CMD.get_logdata(id) 
	local nid = math.floor(id)
	local ok = false
	local query_sql = string.format("select * from `logdata` where id = %d",nid)
	local res = mysql_db:query(query_sql)
    if #res == 0 then
        return ok,nil
    end
    ok = true
    return ok,res[1]
end


function CMD.get_consume_log(uid) 
	local uid = math.floor(uid)
	local ok = false
	local query_sql = string.format("select * from `card_log` where uid = %d and type in (1,8,9,10,11) ORDER BY id DESC limit 0,100",uid)
	local res = mysql_db:query(query_sql)
    if #res == 0 then
        return ok,nil
    end
    ok = true
    return ok,res
end

function CMD.get_order_log(uid) 
	local uid = math.floor(uid)
	local ok = false
	local query_sql = string.format("select * from `card_log` where uid = %d and type in (2,3,4,5,7) ORDER BY id DESC limit 0,100",uid)
	local res = mysql_db:query(query_sql)
    if #res == 0 then
        return ok,nil
    end
    ok = true
    return ok,res
end


-- 更新订单状态
function CMD.update_order_status(data)
	local ok = 0
	local update_sql = string.format("update `order` set status = 1 where plat = '%s' and order_id = '%s'",data.plat,data.order_id)
	local res = mysql_db:query(update_sql)
	local str = json.encode(res)
    if res and not res.errno and res.affected_rows then
        return res.affected_rows
    end
	return ok
end

function CMD.update_gold(data, optype)
	local ok = 0
	if not data.card_add then 
		data.card_add = 0 
	end
	if not data.card_ex then 
		data.card_ex = 0 
	end
	local add_card_num = math.floor(data.card + data.card_add + data.card_ex)
	local update_sql = ""
	local change_type = 0
	if add_card_num > 0 then 
		change_type = add_card_num
		update_sql = string.format("update `user` set gold = gold + %d where uid = %d;", add_card_num, data.uid)
	else
		change_type = 0
		update_sql = string.format("update `user` set gold = gold - %d where uid = %d;", math.abs(add_card_num), data.uid)
	end
	local res = mysql_db:query(update_sql)
	local str = json.encode(res)
    if res and not res.errno and res.affected_rows then
		local query_sql = string.format("select * from `user` where uid = %d",data.uid)
		local user_record = mysql_db:query(query_sql)
		local left = user_record[1].gold 
		skynet.call("MG_SAVE", "lua", "card_log", data.uid, change_type, add_card_num, left, optype,data)
        return add_card_num,left
    end
	return ok
end

function CMD.card_log(uid, change_type, num, left, typ,data)  
	local text = ''
	if data ~= nil then
		text = json.encode(data)
	end
	local query_sql = string.format("insert into `card_log` values(NULL,%d,%d,%d,%d,%d,%d,'%s')",uid, change_type, math.abs(num), left, typ, os.time(),text)
	local res = mysql_db:query(query_sql)
	local ok = false
    if res and res.errno then
        return ok
    end
    ok = res.insert_id
    return ok
end


function CMD.agent_id(uid, agent_id) 
	local query_sql = string.format("select * from `user` where uid = %d",agent_id)
	local agent = mysql_db:query(query_sql) 
	if agent[1] and agent[1].uid > 0 then  --该id  是代理
		local query_sql = string.format("select * from `user` where uid = %d",uid)
		local user_record = mysql_db:query(query_sql)
		local daili_1 = user_record[1].daili_1

		if daili_1 == 0  then --之前没有代理
			local date = os.date("%Y-%m-%d %H:%M:%S");
			local update_sql = string.format("update `user` set daili_1 = %d , daili_2 = %d , daili_3= %d , daili_date='%s' where uid = '%d'",agent_id,agent[1].daili_1,agent[1].daili_2,date,uid)
			local res = mysql_db:query(update_sql)


			local update_sql = string.format("update `user` set daili_2 = %d , daili_3= %d where daili_1 = '%d'",agent_id,agent[1].daili_1,uid)
			local res = mysql_db:query(update_sql)

			local update_sql = string.format("update `user` set daili_3= %d where daili_2 = '%d'",agent_id,uid)
			local res = mysql_db:query(update_sql)

			--玩家有10个一级下属 就自动成为代理
			if agent[1].recharge ~= 1 then  --该id  不是代理 
				local query_sql = string.format("select count(uid) as num from `user` where daili_1 = %d",agent_id)
				local agent_count = mysql_db:query(query_sql) 
				if agent_count[1].num > 0 then  --玩家有10个一级下属  就自动成为代理
					local update_sql = string.format("update `user` set recharge= 1 where uid = '%d'",agent_id)
					local res = mysql_db:query(update_sql)
				end
			end
			return 1
		end 
	end
 	return 0

end

function CMD.get_activity( uid )             
	local query_sql = string.format("select * from activity where uid = %d limit 0,1",uid)
	local res = mysql_db:query(query_sql) 
    if #res == 0 then
        return 1
    else
    	return 0
    end 
end

skynet.start(function()
    start_mysql(mysql_args)
	start_redis(redis_conf)
	skynet.dispatch("lua", function(_,_, command, ...)
		local f = CMD[command]
		skynet.ret(skynet.pack(f(...)))
	end)
	skynet.register "MG_SAVE"
end)

